<?php

namespace App\Http\Controllers\API;

use App\ExpertGroup;
use App\Http\Controllers\Controller;
use App\LoginError;
use App\Services\AuthService;
use App\Services\LogService;
use App\User;
use Auth;
use Request;
use Validator;
use Session;
use geetest\Facades\geetest;

class AuthAPIController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth', [
            'except' => ['applicantRegister', 'userLogin'],
        ]);
        $this->authSvc = new AuthService;
        $this->logSvc = new LogService;
    }

    //applicant
    public function applicantRegister()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'username' => 'required|min:3|max:16',
            'email' => 'required|email',
            'password' => 'required|min:8',
            'entity_type' => 'required',
            'name' => 'required',
            'tel' => 'required',
        ]);
        if ($validator->fails()) die($validator->messages()->first());
        $adminAdd = false;
        if (Request::has('admin_add')) {
            $adminAdd = Request::get('admin_add');
        }
        if ($data['entity_type'] === 'personal') {
            $validator = Validator::make($data, [
                'work_org_name' => 'required',
            ]);
            if ($validator->fails()) die($validator->messages()->first());
        } else if (!$adminAdd) {
            $validator = Validator::make($data, [
                'org_biz_lic_photo' => 'required',
                'org_contact' => 'required',
            ]);
            if ($validator->fails()) die($validator->messages()->first());
        }
        $password = @$this->authSvc->decryptClientPassword($data['password']);
        if (!$this->authSvc->checkPasswordFormat($password)) {
            $result = ['ok' => false, 'message' => '密码格式不正确'];
            return $this->json($result);
        }
        $data['password'] = $password;
        $user = $this->authSvc->getUserByEmail($data['email']);
        if ($user) {
            $result = ['ok' => false, 'message' => '注册失败：该邮箱已经注册过，请登录或更换其他邮箱'];
            return $this->json($result);
        }
        $user = $this->authSvc->getUserByUsername($data['username']);
        if ($user) {
            $result = ['ok' => false, 'message' => '注册失败：该用户名已经注册过，请登录或更换其他用户名'];
            return $this->json($result);
        }
        if ($data['entity_type'] == 'personal') {
            $user = $this->authSvc->createPersonalApplicant($data['username'], $data['email'], $data['password'], $data['name'], $data['tel'], $data['work_org_name'], $adminAdd);
        } else {
            $user = $this->authSvc->createOrgApplicant($data['username'], $data['email'], $data['password'], $data['name'], $data['org_biz_lic_photo'], $data['org_contact'], $data['tel'], $adminAdd);
        }
        $result = ['ok' => true, 'redirect_to' => '/apply/login'];
        $this->logSvc->sinfo('注册', null, $user, null);
        return $this->json($result);
    }

    public function userLogin()
    {
        $data = Request::all();
        $needCode = Request::get('needCode');
        $message =  [
            'username.required' => '请输入用户名',
            'password.required' => '请输入密码',
        ];
        $rules = [
            'username' => 'required|min:2',
            'password' => 'required|min:8',
            'role'     => 'required'
        ];
        if ($needCode) {
            $rules['code'] = 'required|captcha';
            $message['code.require'] = '请输入验证码';
            $message['code.captcha'] = '验证码输入错误';
        }
        $validator = Validator::make($data, $rules, $message);
        if ($validator->fails()) {
            $result = ['ok' => false, 'message' => $validator->errors()->first()];
            return $this->json($result);
        }

        $password = @$this->authSvc->decryptClientPassword($data['password']);
        if (empty($password)) die('Bad request'); // 非正常提交

        /**
         * @edit
         * @time 2020-06-08
         * @需求：记录用户登陆错误次数
         * @调整：session 改为 db
         * @start
         */
        $ip = Request::getClientIp();
//        $ip = str_replace('.', '_', $ip);
//        $errorSessionKey = 'count_of_login_error_' . $ip;
        if (!LoginError::CheckIpErrorNum($ip)) {
            $result = [
                'ok'      => false,
                'message' => '账号或密码输入错误次数过多，由于安全原因请联系管理员(告知管理员您的ip：'.$ip.')',
                //'count_of_login_error' => $countOfLoginError
            ];
            return $this->json($result);
        }
//        if (Session::has($errorSessionKey) && Session::get($errorSessionKey) >= 6) {
//            $countOfLoginError = Session::get($errorSessionKey);
//            $result = ['ok' => false, 'message' => '账号或密码输入错误次数过多，由于安全原因请联系管理员', 'count_of_login_error' => $countOfLoginError];
//            return $this->json($result);
//        }
        /**
         * @end
         */

        $data['password'] = $password;
        $roles = explode(',', $data['role']);
        $user = $this->authSvc->getUserByRolesUsernamePassword($roles, $data['username'], $data['password']);
        if ($user) {
            if ($user->status != '正常') {
                $result = ['ok' => false, 'message' => '账号已停用, 请联系管理员'];
            } else {
                Auth::login($user, true);
                Session::put('login_role', $data['role']);

                /**
                 * @edit
                 * @time 2020-06-08
                 * @需求：记录用户登陆错误次数
                 * @调整：session 改为 db
                 * @start
                 */

                LoginError::ClearErrorNum($ip);
//                if (Session::has($errorSessionKey)) {
//                    Session::forget($errorSessionKey);
//                }
                /**
                 * @end
                 */


                $this->logSvc->sinfo('登录', null, $user, null);
//                if ($user->isApplicant()) {
//                    $redirectTo = '/home';
//                } elseif ($user->isNominator()) {
//                    $redirectTo = '/home';
//                } elseif ($user->isReviewer()) {
//                    $redirectTo = '/home/review';
//                } elseif ($user->isMeetingReviewer()) {
//                    $redirectTo = '/meeting-review/list-projects';
//                } elseif ($user->isCommittee()) {
//                    $redirectTo = '/committee';
//                } elseif ($user->isAdmin() || $user->isStaff()) {
//                    $redirectTo = '/admin';
//                } else {
//                    $redirectTo = '/';
//                }

                switch ($data['role']){
                    case 'admin':
                        $redirectTo = '/admin';
                        break;
                    case 'staff':
                        $redirectTo = '/admin';
                        break;
                    case 'meeting_reviewer':
                        $redirectTo = '/meeting-review/list-projects';
                        break;
                    case 'applicant':
                        $redirectTo = '/home';
                        break;
                    case 'committee':
                        $redirectTo = '/committee';
                        break;
                    case 'reviewer':
                        $redirectTo = '/home/review';
                        break;
                    default:
                        $redirectTo = '/';
                }

                $result = ['ok' => true, 'redirect_to' => $redirectTo];
            }
        } else {
            /**
             * @edit
             * @time 2020-06-08
             * @需求：记录用户登陆错误次数
             * @调整：session 改为 db
             * @start
             */
            LoginError::UpdateIpErrorNum($ip);
            $result = [
                'ok' => false,
                'message' => '用户名或密码不正确'
            ];
//            if (Session::has($errorSessionKey)) {
//                $countOfLoginError = Session::get($errorSessionKey);
//                $countOfLoginError++;
//            } else {
//                $countOfLoginError = 1;
//            }
//            Session::put($errorSessionKey, $countOfLoginError);
//            $result = ['ok' => false, 'message' => '用户名或密码不正确', 'count_of_login_error' => $countOfLoginError];
            /**
             * @end
             */
        }
        return $this->json($result);
    }

    public function changePassword()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'password' => 'required',
        ]);
        if ($validator->fails()) {
            $result = ['ok' => false, 'message' => '密码格式不正确'];
            return $this->json($result);
        }
        $password = @$this->authSvc->decryptClientPassword($data['password']);
        if (!$this->authSvc->checkPasswordFormat($password)) {
            $result = ['ok' => false, 'message' => '密码格式不正确'];
            return $this->json($result);
        }
        $data['password'] = $password;
        $user = Request::user();
        $this->authSvc->resetUserPassword($user, $data['password']);
        $this->logSvc->sinfo('修改密码', null, $user, null);
        return $this->json(['ok' => true]);
    }

    //admin
    public function adminChangeUserPassword()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'password' => 'required',
            'user_id' => 'required'
        ]);
        if ($validator->fails()) {
            $result = ['ok' => false, 'message' => '密码格式不正确'];
            return $this->json($result);
        }
        $password = @$this->authSvc->decryptClientPassword($data['password']);
        if (!$this->authSvc->checkPasswordFormat($password)) {
            $result = ['ok' => false, 'message' => '密码格式不正确'];
            return $this->json($result);
        }
        $data['password'] = $password;
        $actUser = Request::user();
        if (!$actUser->isAdmin()) {
            return $this->json(['ok' => false, 'message' => '非管理员无操作权限']);
        }
        $user = User::find($data['user_id']);
        if (empty($user)) {
            return $this->json(['ok' => false, 'message' => '该用户不存在']);
        }
        $this->authSvc->resetUserPassword($user, $data['password']);
        $this->logSvc->sinfo('修改密码', null, $user, null);
        return $this->json(['ok' => true]);
    }

    public function getCertifyingOrgUsers()
    {
        $keyword = '';
        if (Request::has('keyword')) {
            $keyword = Request::get('keyword');
        }
        $orgUsers = $this->authSvc->getOrgCertifyUser($keyword)->toArray();
        return $this->json($orgUsers);
    }

    public function changeOrgUsersCertifyStatus()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'user_id' => 'required',
            'status' => 'required',
        ]);
        if ($validator->fails()) die; // 非正常提交
        $user = User::find($data['user_id']);
        if (empty($user)) die;
        $this->authSvc->changeOrgUsersCertifyStatus($user, $data['status']);
        $certifyStatus = $data['status'] == 'pass' ? '通过' : '不通过';
        $this->logSvc->sinfo("单位用户认证-{$certifyStatus}", null, $user, null);
        return $this->json(['ok' => true]);
    }

    public function deleteUser()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'user_id' => 'required',
        ]);
        if ($validator->fails()) die;
        $actUser = Request::user();
        if (!$actUser->isAdmin()) {
            return $this->json(['ok' => false, 'message' => '无删除用户权限']);
        }
        $deleteUser = User::find($data['user_id']);
        if (empty($deleteUser)) {
            return $this->json(['ok' => false, 'message' => '该用户不存在']);
        }
        if ($deleteUser->isReviewer()) {
            $canBeDeleted = $this->authSvc->checkReviewerInExpertGroup($deleteUser);
            if (!$canBeDeleted) {
                return $this->json(['ok' => false, 'message' => '该评审专家已被分配到评审小组， 不可删除']);
            }
        }
        $this->authSvc->deleteUser($deleteUser);
        $this->logSvc->sinfo("删除用户", null, $deleteUser, null);
        return $this->json(['ok' => true]);
    }

    public function reUploadOrgBizLicPhoto()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'photo_path' => 'required'
        ]);
        if ($validator->fails()) die;
        $user = Request::user();
        if (empty($user)) {
            return $this->json(['ok' => false, 'message' => '用户不存在']);
        }
        $this->authSvc->changeUserOrgBizLicPhoto($user, $data['photo_path']);
        $this->logSvc->sinfo("重新上传营业执照", null, $user, null);
        return $this->json(['ok' => true]);
    }

    public function getApplicantUsersPageData()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'page' => 'required',
            'pageSize' => 'required',
            'filters' => 'required'
        ]);
        if ($validator->fails()) die;
        $data = $this->authSvc->getApplicantUsersPageData($data);
        return $this->json($data);
    }

    public function updateApplicantInfoById()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'user_id' => 'required',
            'target' => 'required',
        ]);
        if ($validator->fails()) die;
        $user = User::find($data['user_id']);
        if (empty($user)) {
            return $this->json(['ok' => false, 'message' => '该用户不存在']);
        }
        $user_1 = $this->authSvc->getUserByEmail($data['target']['email'], true, $user->id);
        if ($user_1) {
            $result = ['ok' => false, 'message' => '该邮箱已被使用，请更换其他邮箱'];
            return $this->json($result);
        }
        $user_2 = $this->authSvc->getUserByUsername($data['target']['username'], true, $user->id);
        if ($user_2) {
            $result = ['ok' => false, 'message' => '该用户名已被使用，请更换其他用户名'];
            return $this->json($result);
        }
        $this->authSvc->updateUserInfoByTargetInfo($user, $data['target']);
        return $this->json(['ok' => true]);
    }

    public function deleteExpertGroup()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'group_id' => 'required',
        ]);
        if ($validator->fails()) die; // 非正常删除
        $user = Request::user();
        $group = ExpertGroup::find($data['group_id']);
        if ($user->isAdmin() == false) {
            $result = ['ok' => false, 'message' => "非管理员无权删除评审专家分组"];
            return $this->json($result);
        }
        if ($group->isLocked()) {
            $result = ['ok' => false, 'message' => "该评审小组已锁定，不可删除"];
            return $this->json($result);
        }
        $deleteType = $data['type'];
        if ($deleteType === 0) {
            $canDelete = $this->authSvc->canDeleteExpertGroup($group);
            if (!$canDelete) {
                $result = ['ok' => true, 'message' => "该专家组下已分配专家，确认删除？"];
                return $this->json($result);
            }
        }
        $this->authSvc->deleteExpertGroup($group);
        $result = ['ok' => true];
        return $this->json($result);
    }

    public function getExpertGroupsPageData()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'page' => 'required',
            'pageSize' => 'required',
            'filters' => 'required'
        ]);
        if ($validator->fails()) die;
        $user = Request::user();
        if (!$user->isAdmin()) {
            $result = ['ok' => false, 'message' => "非管理员无权获取"];
            return $this->json($result);
        }
        $data = $this->authSvc->getExpertGroupsPageData($data);
        return $this->json($data);
    }

    public function getAddGroupExpertInfo()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'group_id' => 'required',
        ]);
        if ($validator->fails()) die;
        $user = Request::user();
        if (!$user->isAdmin()) {
            $result = ['ok' => false, 'message' => "非管理员无权获取"];
            return $this->json($result);
        }
        $unAllocatedProjects = $this->authSvc->getCanBeAllocatedExperts($data['filters'], $data['group_id']);
        $result = ['ok' => true, 'unAllocatedProjects' => $unAllocatedProjects];
        return $this->json($result);
    }

    public function getSelectedGroupExpertInfo()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'group_id' => 'required',
        ]);
        if ($validator->fails()) die;
        $user = Request::user();
        if (!$user->isAdmin()) {
            $result = ['ok' => false, 'message' => "非管理员无权获取"];
            return $this->json($result);
        }
        $group = ExpertGroup::find($data['group_id']);
        $allocatedExperts = $this->authSvc->getAllocatedExperts($data['filters'], $group);
        $result = ['ok' => true, 'allocatedProjects' => $allocatedExperts];
        return $this->json($result);
    }

    public function importExpertsToExpertGroup()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'group_id' => 'required',
        ]);
        if ($validator->fails()) die;
        $user = Request::user();
        if (!$user->isAdmin()) {
            $result = ['ok' => false, 'message' => "非管理员无权操作"];
            return $this->json($result);
        }
        $group = ExpertGroup::find($data['group_id']);
        if ($group->isLocked()) {
            $result = ['ok' => false, 'message' => "该评审小组已锁定，不可修改"];
            return $this->json($result);
        }
        $newRelationsArr = json_decode($data['new_relations'], true);
        $this->authSvc->importExpertsToExpertGroup($group, $newRelationsArr, $data['leader_expert_id']);
        $result = ['ok' => true];
        return $this->json($result);
    }

    public function deleteExpertsInExpertGroup()
    {
        $data = Request::all();
        $validator = Validator::make($data, [
            'group_id' => 'required',
            'delete_expert_ids' => 'required'
        ]);
        if ($validator->fails()) die;
        $user = Request::user();
        if (!$user->isAdmin()) {
            $result = ['ok' => false, 'message' => "非管理员无权操作"];
            return $this->json($result);
        }
        $group = ExpertGroup::find($data['group_id']);
        if ($group->isLocked()) {
            $result = ['ok' => false, 'message' => "该评审小组已锁定，不可修改"];
            return $this->json($result);
        }
        $deleteExpertIds = json_decode($data['delete_expert_ids'], true);
        $this->authSvc->deleteExpertsInExpertGroupByIds($data['group_id'], $deleteExpertIds);
        $result = ['ok' => true];
        return $this->json($result);
    }

}